package com.shop.cereshop.app.service.activity.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.shop.cereshop.app.dao.activity.CereBuyerCouponDAO;
import com.shop.cereshop.app.page.index.Product;
import com.shop.cereshop.app.page.product.ProductCoupon;
import com.shop.cereshop.app.param.coupon.ActivityParam;
import com.shop.cereshop.app.param.coupon.CouponListParam;
import com.shop.cereshop.app.param.coupon.CouponParam;
import com.shop.cereshop.app.param.coupon.OrderCouponParam;
import com.shop.cereshop.app.redis.service.api.StringRedisService;
import com.shop.cereshop.app.service.activity.CereBuyerCouponService;
import com.shop.cereshop.app.service.activity.CerePlatformActivityDetailService;
import com.shop.cereshop.app.service.buyer.CereBuyerShopCouponService;
import com.shop.cereshop.app.service.coupon.CereShopCouponService;
import com.shop.cereshop.app.service.redis.CereRedisKeyServcice;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.constant.StringEnum;
import com.shop.cereshop.commons.domain.activity.CereBuyerCoupon;
import com.shop.cereshop.commons.domain.buyer.CereBuyerShopCoupon;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import com.shop.cereshop.commons.domain.common.Page;
import com.shop.cereshop.commons.domain.tool.CereShopCoupon;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.TimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

@Service
public class CereBuyerCouponlServiceImpl implements CereBuyerCouponService {

    @Autowired
    private CereBuyerCouponDAO cereBuyerCouponDAO;

    @Autowired
    private StringRedisService stringRedisService;

    @Autowired
    private CereRedisKeyServcice cereRedisKeyServcice;

    @Autowired
    private CereBuyerCouponService cereBuyerCouponService;

    @Autowired
    private CerePlatformActivityDetailService cerePlatformActivityDetailService;

    @Autowired
    private CereShopCouponService cereShopCouponService;

    @Autowired
    private CereBuyerShopCouponService cereBuyerShopCouponService;

    @Override
    public Integer findByActivity(ProductCoupon tool) {
        return cereBuyerCouponDAO.findByActivity(tool);
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void takeCoupon(CouponParam param, CereBuyerUser user) throws CoBusinessException, Exception {
        String time = TimeUtils.yyMMddHHmmss();
        if (!EmptyUtils.isLongEmpty(param.getCouponId())) {
            //平台优惠券领取,校验是否已领取
            CereBuyerCoupon buyerCoupon = cereBuyerCouponDAO.findByCouponId(param.getCouponId(), user.getBuyerUserId());
            if (buyerCoupon != null) {
                throw new CoBusinessException(CoReturnFormat.COUPON_ALREADY_HAVE);
            }
            //查询优惠券数据
            CereBuyerCoupon cereBuyerCoupon = cerePlatformActivityDetailService.findByCouponId(param.getCouponId());
            if (cereBuyerCoupon != null) {
                cereBuyerCoupon.setBuyerUserId(user.getBuyerUserId());
                cereBuyerCoupon.setCreateTime(time);
                cereBuyerCoupon.setState(IntegerEnum.COUPON_HAVE.getCode());
                cereBuyerCouponDAO.insert(cereBuyerCoupon);
                //新增redis延时任务修改优惠券状态为已过期
                stringRedisService.set(StringEnum.COUPON_OVERDUE.getCode() + "-" + cereBuyerCoupon.getBuyerUserId()
                        + "-" + cereBuyerCoupon.getActivityId() + "-" + cereBuyerCoupon.getFullMoney(), 1, TimeUtils.getCountDownByTime(time, cereBuyerCoupon.getEndTime()));
                //新增redis记录数据
                cereRedisKeyServcice.add(StringEnum.COUPON_OVERDUE.getCode() + "-" + cereBuyerCoupon.getBuyerUserId()
                        + "-" + cereBuyerCoupon.getActivityId() + "-" + cereBuyerCoupon.getFullMoney(), cereBuyerCoupon.getEndTime());
            }
        } else if (!EmptyUtils.isLongEmpty(param.getShopCouponId())) {
            //店铺优惠券领取,查询优惠券数据
            CereShopCoupon cereShopCoupon = cereShopCouponService.findById(param.getShopCouponId());
            if (cereShopCoupon != null) {
                //校验库存数量是否充足
                if (cereShopCoupon.getStockNumber() <= 0) {
                    throw new CoBusinessException(CoReturnFormat.COUPON_RECEIVE_FINISH);
                }
                if (IntegerEnum.COUPON_RECEIVE_TYPE_LIMITED.getCode().equals(cereShopCoupon.getReceiveType())) {
                    //限制领取次数,校验是否超出领取限制
                    //查询已领取次数
                    int count = cereBuyerShopCouponService.findCount(user.getBuyerUserId(), cereShopCoupon.getShopCouponId());
                    if (cereShopCoupon.getFrequency() - count < 1) {
                        throw new CoBusinessException(CoReturnFormat.COUPON_TAKE_UPPER_LIMIT);
                    }
                }
                CereBuyerShopCoupon cereBuyerShopCoupon = new CereBuyerShopCoupon();
                cereBuyerShopCoupon.setState(IntegerEnum.COUPON_HAVE.getCode());
                cereBuyerShopCoupon.setReduceMoney(cereShopCoupon.getCouponContent());
                cereBuyerShopCoupon.setFullMoney(cereShopCoupon.getThreshold());
                cereBuyerShopCoupon.setStartTime(cereShopCoupon.getEffectiveStart());
                cereBuyerShopCoupon.setEndTime(cereShopCoupon.getEffectiveEnd());
                cereBuyerShopCoupon.setCouponName(cereShopCoupon.getCouponName());
                cereBuyerShopCoupon.setCreateTime(time);
                cereBuyerShopCoupon.setShopCouponId(cereShopCoupon.getShopCouponId());
                cereBuyerShopCoupon.setBuyerUserId(user.getBuyerUserId());
                cereBuyerShopCoupon.setCouponType(cereShopCoupon.getCouponType());
                cereBuyerShopCouponService.insert(cereBuyerShopCoupon);
                //更新库存数量
                cereShopCoupon.setStockNumber(cereShopCoupon.getStockNumber() - 1);
                cereShopCouponService.updateByPrimaryKeySelective(cereShopCoupon);
                //新增redis延时任务修改优惠券状态为已过期
                stringRedisService.set(StringEnum.SHOP_COUPON_OVERDUE.getCode() + "-" + cereBuyerShopCoupon.getId()
                        , 1, TimeUtils.getCountDownByTime(time, cereBuyerShopCoupon.getEndTime()));
                //新增redis记录数据
                cereRedisKeyServcice.add(StringEnum.SHOP_COUPON_OVERDUE.getCode() + "-" + cereBuyerShopCoupon.getId()
                        , cereBuyerShopCoupon.getEndTime());
            }
        }
    }

    @Override
    public List<ProductCoupon> getCoupons(Long buyerUserId) throws CoBusinessException {
        List<ProductCoupon> coupons = new ArrayList<>();
        //查询平台优惠券
        List<ProductCoupon> list = cereBuyerCouponDAO.getCoupons(buyerUserId, null);
        //查询店铺优惠券
        List<ProductCoupon> couponList = cereBuyerShopCouponService.getCoupons(buyerUserId, null);

        if (!EmptyUtils.isEmpty(list)) {
            list.forEach(productCoupon -> {
                productCoupon.setContent("满" + productCoupon.getFullMoney().stripTrailingZeros().toPlainString() +
                        "减" + productCoupon.getReduceMoney().stripTrailingZeros().toPlainString() + "元");
                coupons.add(productCoupon);
            });
        }
        if (!EmptyUtils.isEmpty(couponList)) {
            couponList.forEach(productCoupon -> {
                if (IntegerEnum.COUPON_TYPE_REDUTION.getCode().equals(productCoupon.getCouponType())) {
                    productCoupon.setContent("满" + productCoupon.getFullMoney().stripTrailingZeros().toPlainString() +
                            "减" + productCoupon.getReduceMoney().stripTrailingZeros().toPlainString() + "元");
                } else {
                    productCoupon.setContent(productCoupon.getReduceMoney().stripTrailingZeros().toPlainString() + "折券");
                }
                coupons.add(productCoupon);
            });
        }
        return coupons;
    }

    @Override
    public Page getCouponProducts(ActivityParam param) throws CoBusinessException {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<Product> list = null;
        if (!EmptyUtils.isLongEmpty(param.getActivityId())) {
            //平台优惠券商品查询
            list = cereBuyerCouponDAO.getCouponProducts(param);
        } else {
            //店铺优惠券商品查询
            list = cereBuyerCouponDAO.getShopCouponProducts(param);
        }
        PageInfo<Product> pageInfo = new PageInfo<>(list);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public List<ProductCoupon> getOrderCoupons(OrderCouponParam param, CereBuyerUser user) throws CoBusinessException {
        List<ProductCoupon> list = new ArrayList<>();
        if (!EmptyUtils.isEmpty(param.getParams())) {
            param.getParams().forEach(shop -> {
                if (!EmptyUtils.isEmpty(shop.getProducts())) {
                    shop.getProducts().forEach(product -> {
                        //根据店铺id、商品id、商品价格查询满足条件的优惠券
                        List<ProductCoupon> productCoupons = cereBuyerCouponDAO.findCouponByProduct(product.getPrice(),
                                user.getBuyerUserId(), product.getProductId());
                        if (!EmptyUtils.isEmpty(productCoupons)) {
                            productCoupons.forEach(coupon -> {
                                //拼接活动id、满减金额字符串以便去重
                                coupon.setDistinct(coupon.getActivityId() + "-" + coupon.getFullMoney());
                                list.add(coupon);
                            });
                        }
                    });
                }
            });
        }
        List<ProductCoupon> collect = null;
        if (!EmptyUtils.isEmpty(list)) {
            //去除重复活动和对应金额优惠券
            collect = list.stream().collect(
                    Collectors.collectingAndThen(Collectors.toCollection(
                            () -> new TreeSet<>(Comparator.comparing(data -> data.getDistinct()))), ArrayList::new)
            );
        }
        return collect;
    }

    @Override
    public void updateState(CereBuyerCoupon buyerCoupon) throws CoBusinessException {
        cereBuyerCouponDAO.updateState(buyerCoupon);
    }

    @Override
    public List<ProductCoupon> findCouponByProduct(BigDecimal price, Long buyerUserId, Long productId) {
        return cereBuyerCouponDAO.findCouponByProduct(price, buyerUserId, productId);
    }

    @Override
    public List<ProductCoupon> getCouponList(CouponListParam param, CereBuyerUser user) throws CoBusinessException {
        List<ProductCoupon> coupons = new ArrayList<>();
        //查询平台优惠券
        List<ProductCoupon> list = cereBuyerCouponDAO.getCoupons(user.getBuyerUserId(), param.getState());
        //查询店铺优惠券
        List<ProductCoupon> couponList = cereBuyerShopCouponService.getCoupons(user.getBuyerUserId(), param.getState());
        if (!EmptyUtils.isEmpty(list)) {
            list.forEach(productCoupon -> {
                productCoupon.setContent("满" + productCoupon.getFullMoney().stripTrailingZeros().toPlainString() +
                        "减" + productCoupon.getReduceMoney().stripTrailingZeros().toPlainString() + "元");
                coupons.add(productCoupon);
            });
        }
        if (!EmptyUtils.isEmpty(couponList)) {
            couponList.forEach(productCoupon -> {
                if (IntegerEnum.COUPON_TYPE_REDUTION.getCode().equals(productCoupon.getCouponType())) {
                    productCoupon.setContent("满" + productCoupon.getFullMoney().stripTrailingZeros().toPlainString() +
                            "减" + productCoupon.getReduceMoney().stripTrailingZeros().toPlainString() + "元");
                } else {
                    productCoupon.setContent(productCoupon.getReduceMoney().stripTrailingZeros().toPlainString() + "折券");
                }
                coupons.add(productCoupon);
            });
        }
        return coupons;
    }

    @Override
    public CereBuyerCoupon findByCouponId(Long couponId, Long buyerUserId) {
        return cereBuyerCouponDAO.findByCouponId(couponId, buyerUserId);
    }

    @Override
    public void updateBuyerData(Long buyerUserId, Long id) throws CoBusinessException {
        cereBuyerCouponDAO.updateBuyerData(buyerUserId, id);
    }

    @Override
    public void updateByUserIdAndCouponId(CereBuyerCoupon cereBuyerCoupon) throws CoBusinessException {
        cereBuyerCouponDAO.updateByUserIdAndCouponId(cereBuyerCoupon);
    }
}
